package com.example.nightmeel.view;

import java.io.File;
import java.io.FileOutputStream;

import com.example.nightmeel.ItemPostActivity.ShutterClickListener;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.provider.MediaStore.Images;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;

public class CameraView extends SurfaceView implements SurfaceHolder.Callback, Camera.AutoFocusCallback, ShutterClickListener {
	private Camera myCamera;
	private Context context;
	private Boolean bool = true;
	private SaveImageListener mSaveImageListener;
	
	public CameraView(Context context) {
		super(context);
	}
	
	public CameraView(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.context = context;
		getHolder().addCallback(this);
		//getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		mSaveImageListener = (SaveImageListener) context;
	}
	public void surfaceCreated(SurfaceHolder holder) {
		myCamera = Camera.open();
		try {
			myCamera.setPreviewDisplay(holder);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		Camera.Parameters parameters = myCamera.getParameters();
		myCamera.setParameters(parameters);
		myCamera.setDisplayOrientation(90);	// 縦画面対応
		myCamera.startPreview();
	}

	public void surfaceDestroyed(SurfaceHolder holder) {
		myCamera.release();
		myCamera = null;
	}

	// シャッターが押されたときに呼ばれるコールバック
	private Camera.ShutterCallback mShutterListener = new Camera.ShutterCallback() {
		public void onShutter() {

			if (myCamera != null && bool) {
				bool = false;
				myCamera.takePicture(mShutterListener, null, mPictureListener);
			}
		}
	};

	// JPEGイメージ生成後に呼ばれるコールバック
	private Camera.PictureCallback mPictureListener = new Camera.PictureCallback() {
		public void onPictureTaken(byte[] data, Camera camera) {
			if (data != null) {
				if (!sdcardWriteReady()) {
					Toast.makeText(context, "SDCARDが認識されません。",
							Toast.LENGTH_SHORT).show();
					bool = true;
					camera.startPreview();
					return;
				}
				FileOutputStream foStream = null;
				// フォルダのパスを表示します。。
				File file = new File(Environment.getExternalStorageDirectory()
						.getPath() + "/cmr/");
				// フォルダが存在しなかった場合にフォルダを作成します。
				if (!file.exists()) {
					file.mkdir();
				}
				// これで他のとかぶらない名前の設定ができました。
				String imgName = Environment.getExternalStorageDirectory()
						.getPath()
						+ "/cmr/"
						+ System.currentTimeMillis()
						+ ".jpg";

				try {
					Matrix m = new Matrix(); // Bitmapの回転用Matrix
					m.setRotate(90);
					Bitmap original = BitmapFactory.decodeByteArray(data, 0,
							data.length);
					Bitmap rotated = Bitmap.createBitmap(original, 0, 0,
							original.getWidth(), original.getHeight(), m, true);
					
					foStream = new FileOutputStream(imgName);
					rotated.compress(CompressFormat.JPEG, 80, foStream);
					foStream.close();

					ContentValues values = new ContentValues();
					ContentResolver contentResolver = context
							.getContentResolver();
					values.put(Images.Media.MIME_TYPE, "image/jpeg");
					values.put("_data", imgName);
					try {
						Uri uri = contentResolver.insert(
								MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
								values);
						mSaveImageListener.onSaveImage(uri);
					} catch (Exception e) {
						Toast.makeText(context, "再起動後に画像が認識されます。",
								Toast.LENGTH_SHORT).show();
						e.printStackTrace();
					}
				} catch (Exception e) {
					Toast.makeText(context, "ファイルの保存中にエラーが発生しました。",
							Toast.LENGTH_SHORT).show();
					e.printStackTrace();
				}
				bool = true;
			} else {
				Toast.makeText(context, "データが取得できませんでした。", Toast.LENGTH_SHORT)
						.show();
				bool = true;
				camera.startPreview();
			}
		}
	};


	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (event.getAction() == MotionEvent.ACTION_DOWN) {
			if (myCamera != null && bool) {
				bool = false;
				myCamera.autoFocus(this);
			}
	}
		return true;
	}

	@Override
	public void onAutoFocus(boolean success, Camera camera) {
		//camera.startPreview();
		myCamera.takePicture(mShutterListener, null, mPictureListener);
	}
	
	// 書き込みができるかどうかを判別する関数
	private boolean sdcardWriteReady() {
		String state = Environment.getExternalStorageState();
		return (Environment.MEDIA_MOUNTED.equals(state));
	}

	@Override
	public void onShutterClick() {
		if (myCamera != null && bool) {
			bool = false;
			myCamera.autoFocus(this);
			//myCamera.takePicture(mShutterListener, null, mPictureListener);
		}
	}
	
	public interface SaveImageListener {
		public void onSaveImage(Uri uri);
			
		public void onSaveFailedImage();
	}	
}